import {
  defineComponent,
  ref,
  toRefs,
  nextTick,
  watch,
  onMounted,
  onUnmounted,
  useAttrs,
} from 'vue';
import type { PropType } from 'vue';
import { storeToRefs } from 'pinia';

import editor from '/@/store/modules/bpmnEditor';
import modulesAndModdle from './modulesAndModdle';
import initModeler from './initModeler';
import { createNewDiagram } from '/@/utils/bpmn';
import { catchError } from '/@/utils/log';
import modelerStore from '/@/store/modules/bpmnModeler';
import EventEmitter from '/@/utils/bpmn/EventEmitter';
import { getWatchNodeInfo } from '/@/api/flow/flow';

import { BasicModal, useModal } from '/@/components/Modal';

import Legend from './legend.vue';

import '../../styles/node-watch.less';

import { isArray } from 'min-dash';

const Designer = defineComponent({
  name: 'Designer',
  props: {
    xml: {
      type: String as PropType<string>,
      default: undefined,
    },
    readOnly: {
      type: Boolean,
      default: false,
    },
    isColored: {
      type: Boolean,
      default: false,
    },
    finishedInfo: {
      type: Object,
      default: () => ({}),
    },
    flowWorkItemID: {
      type: [String, Number],
      default: '',
    },
    nodeDisabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:xml', 'command-stack-changed'],
  setup(props, { emit }) {
    const attrs = useAttrs();
    const editorStore = editor();
    const { editorSettings } = storeToRefs(editorStore);
    const { xml } = toRefs(props);
    const designer = ref<HTMLDivElement | null>(null);
    const [register, { openModal }] = useModal();
    const title = ref<string>('节点详情');
    const nodeInfoList = ref<any[]>([]);
    const listNode = ref<any>();
    props.nodeDisabled &&
      EventEmitter.on('modeler-init', async (modeler) => {
        modeler.on('element.click', async (event) => {
          let activityStatus = 0;
          let { unfinishedTaskSet } = props.finishedInfo;

          const { $type, name, id } = event.element.businessObject;

          if (!isArray(unfinishedTaskSet)) unfinishedTaskSet = [];
          if (unfinishedTaskSet.includes(id)) {
            activityStatus = 1;
          }
          if ($type === 'bpmn:UserTask') {
            title.value = `${name}（节点详情）`;
            openModal(true);
            getHandleNodeInfo({
              activityName: name,
              activityStatus,
              workItemId: props.flowWorkItemID,
            });
          }
        });
      });

    const init = async () => {
      const modelerModules = modulesAndModdle(editorSettings);

      await nextTick();
      initModeler(designer, modelerModules, props.readOnly, emit);

      await nextTick();
      await createNewDiagram(xml.value, editorSettings.value);

      if (props.finishedInfo.finishedTaskSet) {
        setProcessStatus(props.finishedInfo);
      }
    };
    // 获取当前点击节点审批信息
    const getHandleNodeInfo = async (params: {
      activityName: string;
      activityStatus: number;
      workItemId: number | string;
    }) => {
      const { choiceContent, expiredTime, finishedDate, inceptDate, recipients } =
        await getWatchNodeInfo(params);
      nodeInfoList.value = [
        { label: '节点审批人', value: recipients || '-' },
        { label: '接收时间', value: inceptDate || '-' },
        { label: '结束时间', value: finishedDate || '-' },
        { label: '耗时', value: expiredTime || '-' },
        { label: '审批意见', value: choiceContent || '-' },
      ];

      listNode.value = (
        <div class="node-container">
          {nodeInfoList.value.map((item) => (
            <div class="node-item">
              <div class="node-label">{item.label}</div>
              <div class="node-value">{item.value}</div>
            </div>
          ))}
        </div>
      );
    };
    // 提取已流转中的网关节点
    const getGateWay = (finished: string[], gateWay: string[]): string[] => {
      const data1 = Array.isArray(finished) ? finished : [];
      const data2 = Array.isArray(gateWay) ? gateWay : [];
      return data2.filter((i) => data1.includes(i));
    };
    // 提取已流转中的结束节点
    const getEndNode = (finished: string[]): string[] => {
      const data1 = Array.isArray(finished) ? finished : [];

      return data1.filter((i) => i.indexOf('end_') != -1);
    };

    // 设置流程图元素状态
    function setProcessStatus(processNodeInfo) {
      const store = modelerStore();
      const theme = editorSettings.value.theme;
      const { finishedSequenceFlowSet, finishedTaskSet, unfinishedTaskSet, gatewaySet, unUsedSet } =
        processNodeInfo;
      const canvas: any = store.getCanvas;
      const elementRegistry: any = store.getElRegistry;

      if (Array.isArray(finishedSequenceFlowSet)) {
        finishedSequenceFlowSet.forEach((item) => {
          if (item != null) {
            canvas.addMarker(item, 'success');

            const element = elementRegistry.get(item);

            const conditionExpression = element.businessObject.conditionExpression;
            if (conditionExpression) {
              canvas.addMarker(item, 'condition-expression');
            }
          }
        });
      }
      if (Array.isArray(finishedTaskSet)) {
        const refuseList = getGateWay(finishedTaskSet, gatewaySet);
        const endList = getEndNode(finishedTaskSet);
        finishedTaskSet.forEach((item) => {
          canvas.addMarker(item, `success${theme}`);
          if (refuseList.includes(item)) {
            canvas.addMarker(item, 'refuse');
          } else if (endList.includes(item)) {
            canvas.addMarker(item, `end${theme}`);
          } else {
            canvas.addMarker(item, `success${theme}`);
          }
        });
      }
      if (Array.isArray(unfinishedTaskSet)) {
        unfinishedTaskSet.forEach((item) => {
          canvas.addMarker(item, `current${theme}`);
        });
      }
      if (Array.isArray(unUsedSet)) {
        unUsedSet.forEach((item) => {
          canvas.addMarker(item, `unset${theme}`);
        });
      }
    }

    watch(
      () => editorSettings.value,
      async () => {
        catchError(init);
      },
      { deep: true, immediate: false },
    );
    watch(
      () => props.finishedInfo,
      async (val) => {
        if (val.finishedTaskSet) {
          setProcessStatus(val);
        }
      },
      { deep: true },
    );
    onMounted(() => {
      catchError(init);
    });

    onUnmounted(() => {
      EventEmitter.removeAllListeners('modeler-init');
    });

    return () => {
      return (
        <div class="designer-container flex-1">
          {props.readOnly && <Legend />}
          <div
            ref={designer}
            class={`designer ${props.readOnly && !props.isColored ? 'designer-readonly' : ''}`}
          ></div>
          {props.nodeDisabled && (
            <BasicModal
              vModel={attrs}
              title={title.value}
              onRegister={register}
              showCancelBtn={false}
              showOkBtn={false}
              minHeight={330}
            >
              {listNode.value}
            </BasicModal>
          )}
        </div>
      );
    };
  },
});

export default Designer;
